package com.enjoy.seata.service.impl;

import com.enjoy.seata.service.AccountService;
import com.enjoy.seata.service.BusinessService;
import com.enjoy.seata.service.OrderService;
import com.enjoy.seata.service.StoreService;
import io.seata.core.exception.TransactionException;
import io.seata.rm.RMClient;
import io.seata.tm.TMClient;
import io.seata.tm.api.GlobalTransaction;
import io.seata.tm.api.GlobalTransactionContext;


public class BusinessServiceImpl implements BusinessService {


    private StoreService storeService;

    private OrderService orderService;

    private AccountService accountService;


    @Override
    public void purchase(String userId, String commodityCode, int commodityCount, int money) {

        accountService = new AccountServiceImpl();
        storeService = new StoreServiceImpl();
        orderService = new OrderServiceImpl();
        orderService.setAccountService(accountService);

        // reset data
        accountService.reset(userId, String.valueOf(money));
        storeService.reset(commodityCode, String.valueOf(commodityCount));
        orderService.reset(null, null);

        // init seata
        String applicationId = "api";
        String txServiceGroup = "my_test_tx_group";
        TMClient.init(applicationId, txServiceGroup);
        RMClient.init(applicationId, txServiceGroup);

        GlobalTransaction tx = GlobalTransactionContext.getCurrentOrCreate();
        try {
            tx.begin(60000, "testBiz");
            System.out.println("begin tx,xid is" + tx.getXid());
            // biz operate 3 datasource
            // set >= 5 will be rollback(200*5>999) else will be commit
            int opCount = 5;

            storeService.deduct(commodityCode, 5);
            orderService.create(userId, commodityCode, opCount);

            boolean needCommit = ((StoreServiceImpl) storeService).validNegativeCheck("count", commodityCode) && ((AccountServiceImpl) accountService).validNegativeCheck("money", userId);

            if (needCommit) {
                tx.commit();
            } else {
                System.out.println("rollback trx, cause: data negative, xid is " + tx.getXid());
                tx.rollback();
            }

        } catch (Exception e) {
            System.out.println("rollback " + tx.getXid());
            try {
                tx.rollback();
            } catch (TransactionException transactionException) {
                transactionException.printStackTrace();
            }
        }

    }
}
